package br.ufg.inf.espweb.sgca.dao.impl;

import br.ufg.inf.espweb.sgca.dao.GenericDao;
import br.ufg.inf.espweb.sgca.model.Entidade;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author diCastro
 */
@Transactional(propagation = Propagation.REQUIRED)
public abstract class GenericDaoImpl<T extends Entidade> implements GenericDao<T>, Serializable{
    
    protected abstract EntityManager getEntityManager();
    
    protected abstract Class<T> getEntityClass();
    
    @Override
    public Session getSession() {
        return (Session) getEntityManager().getDelegate();
    }
    
    @Override
    public void salvar(T entidade) {
        getEntityManager().persist(entidade);
    }

    @Override
    public void atualizar(T entidade) {
        getEntityManager().merge(entidade);
    }

    @Override
    public T buscarPorId(Long id) {
        Criteria criteria = getSession().createCriteria(getEntityClass());
        criteria.add(Restrictions.eq("id", id)).setMaxResults(1);
        
        return (T) criteria.uniqueResult();
    }

    @Override
    public List<T> listarTodos() {
        Criteria criteria = getSession().createCriteria(getEntityClass());
        return criteria.list();
    }

    @Override
    public void remover(Long id) {
        T entidade = buscarPorId(id);
        getEntityManager().merge(entidade);
        getEntityManager().remove(entidade);
    }
}
